/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "ui图像视频.h"

#include "../ui绘制模板.h"
#include "core/属性.h"
#include "UI/UI.h"

#include "MBT_Engine.h"

#include "底层绘图/S_纹理.h"


static uint16 g视频框属性ID = 0;
static uint16 g视频框变换ID = 0;
static uint16 g视频框颜色ID = 0;
static uint16 g视频框元素ID = 0;
//static uint16 g视频框属性ID = 0;

static uint16 g捕捉点变换ID = 0;
static uint16 g捕捉点颜色ID = 0;
static uint16 g捕捉点元素ID = 0;


//DEF_单色绘制ID(选框);


static void f_draw视频框(C_Widget* self, S_2D画布* 画布) {
	C_视频框* view = dynamic_cast<C_视频框*>(self);

	view->m_框部件.m_属性 = f_vg_gen属性(画布);
	S_凸边图元 图元{};
	图元.属性 = f_vg_get属性(画布, view->m_框部件.m_属性);
	view->m_框部件.f_Draw(画布, 图元, E_笔刷类型::e_单色填充);


	//static S_纹理* 占位纹理 = f_tex_创建图像纹理(view->m_UIctx->m_Ctx, {16,16,1}, E_纹理格式::e_tf_RGBA8U_U, E_纹理维度类型::e_2D);
	//f_tex_安装纹理采样器(占位纹理, view->m_UIctx->m_Mat->m_采样器);
	

	view->m_视口纹理绘制.f_Draw(画布, view->m_框部件.m_属性, E_笔刷类型::e_纹理, view->m_帧纹理[0]);

	
	//view->m_帧[0] = 占位纹理;
	//
	//g视频框属性ID = f_vg_gen属性(画布);
	//view->m_笔刷 = f_vg_gen图像笔刷(画布, g视频框属性ID, g视频框变换ID, 占位纹理);
	//
	//g视频框元素ID = f_vg_画纹理面(画布, view->m_笔刷);
	//f_vg_set实例数量(画布, g视频框元素ID, 1);
	//
	//f_vg_set单色(画布, g视频框颜色ID, 0, { 10,10,10,255 });

	//======================== 捕捉点绘制 ===============================
	{
		//g捕捉点变换ID = f_vg_gen变换(画布);
		//g捕捉点颜色ID = f_vg_gen颜色(画布);
		//auto pen = f_vg_gen单色描边(画布, g捕捉点变换ID, g捕捉点颜色ID, g视频框属性ID);
		//g捕捉点元素ID = f_vg_绘制矩形(画布, pen, false);
	}
	
	//======================== 选框绘制 ============================
	{
		//f_ui绘制模板_选框绘制(画布, gid_选框绘制变换, gid_选框绘制颜色, gid_选框绘制元素, g视频框属性ID);
	}

	//if (view->m_帧.size()) {
	//	//f_vg_set纹理(view->m_笔刷, 0, view->m_帧[0]);
	//	//S_绘图设备配置* pip = (S_绘图设备配置*)(view->m_帧[0]->m_Ctx->m_绘图设备);
	//	std::vector<uint8> data(16 * 16 * 4, 100);
	//	f_tex_填充纹理数据(view->m_帧[0], data.data(), sizeof(S_RGBA8UI), { 16,16,1 });
	//	f_tex_安装纹理采样器(view->m_帧[0], view->m_UIctx->m_Mat->m_采样器);
	//}
}


static void f_set视频框部件变换(C_Widget* self) {
	C_视频框* view = dynamic_cast<C_视频框*>(self);

	S_2D_PanelAttr 属性 = {};
	//属性.m_偏移 = self->m_Pos;
	
	属性.m_Offset = self->m_父部件->m_扩展视口属性->m_中心;
	属性.m_Scale = self->m_父部件->m_扩展视口属性->m_比例;
	
	f_vg_set属性(self->m_画布, g视频框属性ID, 属性);
	//
	//
	view->m_框部件.f_alloc(1);
	mat3X2 变换 = {};
	变换.row0 = {};
	变换.row1 = self->f_getOriginalSize();
	变换.row2 = {1,0};
	view->m_框部件.f_set单色填充(0, 变换, {255,255,255,255}, S_Widget预设凸包图元::m_矩形);


	view->m_视口纹理绘制.f_alloc(1);
	view->m_视口纹理绘制.f_set(0, 变换, S_Widget预设凸包图元::m_矩形, {0,0,255,255});
	view->m_视口纹理绘制.f_绑定纹理(view->m_帧纹理[0], 0);
	
}


static void f_播放视频框动画(C_Widget* self) {
	C_视频框* view = dynamic_cast<C_视频框*>(self);

	if (view->m_槽纹理更新) {
		//f_vg_set纹理(view->m_笔刷, 0, view->m_帧[0]);
		//f_tex_安装纹理采样器(view->m_帧[0], view->m_UIctx->m_Mat->m_采样器);

		view->m_槽纹理更新 = false;
	}
	
}



C_视频框::C_视频框(S_UI渲染环境& ctx, uint8 缓存数量) :C_Widget(&ctx) {
	mf_变换 = f_set视频框部件变换;
	mf_绘制 = f_draw视频框;
	mf_动画 = f_播放视频框动画;

	m_笔刷 = {};
	m_帧纹理.resize(缓存数量);
	for (uint32 i = 0; i < 缓存数量; ++i) {
		m_帧纹理[i] = S_全局缓存::g_空纹理;
	}

	m_槽纹理更新 = false;
}

C_视频框::~C_视频框() {
}

void C_视频框::f_填充像素(uint8* pix, uvec3 dim, uint8 color_bit) {
	f_tex_填充纹理数据(m_帧纹理[0], pix, sizeof(S_RGB8UI), { 16,16,1 });
}

void C_视频框::f_set槽纹理(S_纹理* tex, uint8 offset) {
	m_帧纹理[offset] = tex;
	m_槽纹理更新 = true;

	f_tex_安装纹理采样器(tex, m_UIctx->m_Mat->m_采样器);
}

void f_ui_set视频图像视口绘制纹理(C_Widget* self, S_纹理* tex) {
	C_视频框& box = *dynamic_cast<C_视频框*>(self);
	box.m_帧纹理[0] = tex;
	box.m_更新绘制属性 = true;
	box.m_视口纹理绘制.f_绑定纹理(tex, 0);

	box.f_setOriginalSize(_Vec2(tex->m_Size));
	//box.f_setSize(_Vec2(tex->m_Size));
}



void f_视频框_填充视频捕捉点(C_视频框* box, const std::vector<S_Rect2Df>& 点坐标, const std::vector<S_RGBA8UI>& 点颜色) {
	uint32 num = 点坐标.size();
	if(!num) return;


	f_vg_resize参数实例(box->m_画布, g捕捉点变换ID, num);
	f_vg_resize参数实例(box->m_画布, g捕捉点颜色ID, num);



	mat3X2* 变换 = f_vg_map绘制数据指针<mat3X2>(box->m_画布, g捕捉点变换ID);
	uint32* 颜色 = f_vg_map绘制数据指针<uint32>(box->m_画布, g捕捉点颜色ID);

	const S_Rect2Df* rect = 点坐标.data();
	const S_RGBA8UI* color = 点颜色.data();
	

	for (uint32 i = 0; i < num; ++i) {
		变换[i].row2 = {1,0};
		变换[i].row1 = rect[i].extent;
		变换[i].row0 = rect[i].offset - rect[i].extent*0.5;

		颜色[i] = f_PackData4X8(color[i]);
	}

	f_vg_unmap绘制数据指针(box->m_画布, g捕捉点颜色ID);
	f_vg_unmap绘制数据指针(box->m_画布, g捕捉点变换ID);

	
	f_vg_set实例数量(box->m_画布, g捕捉点元素ID, num);

}

void f_视频框_设置选取(C_视频框* box, const S_Rect2Df& 点坐标, const S_RGBA8UI& 点颜色) {
	//mat3X2 变换;
	//变换.row0 = 点坐标.offset;
	//变换.row1 = 点坐标.extent;
	//变换.row2 = {1, 0};
	//
	//f_vg_set变换(box->m_画布, gid_选框绘制变换, 0, 变换);
	//f_vg_set单色(box->m_画布, gid_选框绘制颜色, 0, 点颜色);
	//
	//f_vg_set实例数量(box->m_画布, gid_选框绘制元素, 1);
}

void f_视频框_关闭选取(C_视频框* box) {
	//f_vg_set实例数量(box->m_画布, gid_选框绘制元素, 0);
}







static void f_图像框视口布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_图像框* box = dynamic_cast<C_图像框*>(self);

}

static void f_draw图像框(C_Widget* self, S_2D画布* 画布) {
	C_图像框* box = dynamic_cast<C_图像框*>(self);

	uint32 属性 = f_vg_gen属性(画布);
	//S_凸边图元 图元{};
	//图元.属性 = f_vg_get属性(画布, box->m_背景绘制.m_属性);
	switch (box->m_纹理绘制类型) {
		case E_笔刷类型::e_多纹理: {
			box->m_背景绘制.f_Draw(画布, 属性, box->m_默认纹理集);
			break;
		}
		default:
			box->m_背景绘制.f_Draw(画布, 属性, box->m_纹理绘制类型);
			break;
	}
}

static void f_图像框部件变换(C_Widget* self) {
	C_图像框* box = dynamic_cast<C_图像框*>(self);

	uint32 属性 = f_vg_gen属性(self->m_画布);
	S_2D_PanelAttr 顶点属性{ {0,0},{1,1},0,0 };

	mat3X2 mat;
	mat.row0 = {};
	mat.row1 = self->m_Size;
	mat.row2 = {6,0};

	box->m_背景绘制.f_alloc(1);
	顶点属性.m_渐变数量 = box->m_背景绘制.f_set(0, mat, S_Widget预设凸包图元::m_圆角矩形, {}, f_prop_TexProp(box->m_纹理属性));

	f_vg_set属性(self->m_画布, 属性, 顶点属性);
	
}


C_图像框::C_图像框(S_UI渲染环境& ctx) :C_Widget(&ctx) {
	mf_布局 = f_图像框视口布局;
	mf_绘制 = f_draw图像框;
	mf_变换 = f_图像框部件变换;

	m_默认纹理集 = nullptr;

	m_纹理 = {};
	m_纹理属性 = {};
}

C_图像框::~C_图像框() {
	if(m_默认纹理集) f_纹理集_销毁(m_默认纹理集);
}


C_Widget* f_ui_创建图像框(S_UI渲染环境& ctx) {
	C_图像框* box = new C_图像框(ctx);
	box->m_纹理绘制类型 = E_笔刷类型::e_纹理;
	return box;
}

C_Widget* f_ui_创建过程纹理图像框(S_UI渲染环境& ctx) {
	C_图像框* box = new C_图像框(ctx);
	box->m_纹理绘制类型 = E_笔刷类型::e_噪波;
	return box;
}

void f_ui_bind图像框纹理属性(C_Widget* self, S_Props& prop) {
	C_图像框* box = static_cast<C_图像框*>(self);
	box->m_纹理属性 = prop;
}

void f_ui_刷新图像框属性(C_Widget* w) {
	w->m_更新绘制属性 = true;
}


C_Widget* f_ui_创建多图像框(S_UI渲染环境& ctx, S_纹理集* 纹理集) {
	C_图像框* box = new C_图像框(ctx);
	box->m_纹理绘制类型 = E_笔刷类型::e_多纹理;

	box->m_默认纹理集 = f_纹理集_创建();

	return box;
}









static void on_纹理绘制模式切换(S_Props& prop) {
	prop.m_UI->m_部件->m_父部件->m_更新绘制属性 = true;
}

static void f_图像集视口绘制(C_Widget* self, S_2D画布* 画布) {
	C_图像集视口& box = *dynamic_cast<C_图像集视口*>(self);
	box.m_纹理绘制 = f_vg_drawTextures(画布, E_纹理类型::e_Tex2D, E_图层混合模式::e_Normal);
}

static void f_图像集视口布局(C_Widget* self, C_Widget** w, uint32 num) {
	C_图像集视口& box = *dynamic_cast<C_图像集视口*>(self);
	w[0]->f_setPos({ 0, self->m_Size.y - 24 });
	w[0]->f_setSize({self->m_Size.x, 24});
}

static void f_图像集视口变换(C_Widget* self) {
	C_图像集视口& box = *dynamic_cast<C_图像集视口*>(self);

	S_GPU内存块* 形状[6] = { &S_2D画布::g预设_矩形 };
	S_2DConvexRect rect[6];
	uint32 纹理ID[6];
	
	f_vg_tranform(self->m_画布, {});

	S_纹理集* ts = box.m_默认纹理集;
	uint32 纹理数量 = 1;
	uint32 元素数量 = 1;

	auto p = f_prop_纹理集(box.m_纹理);
	uint16 纹理绘制类型 = 0;
	uint16 采样器类型 = DEF_ObType_SamplerType_None;

	if (box.m_纹理.m_Type == E_值类型::e_Type_TexSets && p.m_纹理集 && p.m_纹理集->data->count) {
		ts = p.m_纹理集;

		auto tex = f_纹理集_get纹理(p.m_纹理集, 0);
		if (tex) {
			switch (tex->m_类型) {
				case E_纹理维度类型::e_CUBE:
				case E_纹理维度类型::e_CUBE_Array: {
					采样器类型 = DEF_ObType_SamplerType_CubeArray;

					float32 widht = self->m_Size.x / 3;

					//rect[0].offset = { widht * 2, widht };
					//rect[0].size = { widht , widht };
					rect[0].radius = { 1,1 };
					rect[0].AA_type = { 0xffffffff, DEF_ObType_CubeTexDir_PX };

					//rect[1].offset = { 0, widht * 1 };
					//rect[1].size = { widht , widht };
					rect[1].radius = { 1,1 };
					rect[1].AA_type = { 0xffffffff, DEF_ObType_CubeTexDir_NX };

					//rect[2].offset = { widht, 0 };
					//rect[2].size = { widht , widht };
					rect[2].radius = { 1,1 };
					rect[2].AA_type = { 0xffffffff, DEF_ObType_CubeTexDir_PY };

					//rect[3].offset = { widht, widht * 2 };
					//rect[3].size = { widht , widht };
					rect[3].radius = { 1,1 };
					rect[3].AA_type = { 0xffffffff, DEF_ObType_CubeTexDir_NY };

					//rect[4].offset = { widht, widht };
					//rect[4].size = { widht , widht };
					rect[4].radius = { 1,1 };
					rect[4].AA_type = { 0xffffffff, DEF_ObType_CubeTexDir_PZ };

					//rect[5].offset = { widht, widht * 3 };
					//rect[5].size = { widht , widht };
					rect[5].radius = { 1,1 };
					rect[5].AA_type = { 0xffffffff, DEF_ObType_CubeTexDir_NZ };

					元素数量 = 6;
					for (uint32 i = 0; i < 6; ++i) {
						形状[i] = &S_2D画布::g预设_矩形;
						纹理ID[i] = p.m_激活ID;
					}
					break;
				}
				default: {
					采样器类型 = DEF_ObType_SamplerType_2DArray;

					//rect[0].offset = {};
					//rect[0].size = self->m_Size;
					//rect[0].size.y -= 24;
					rect[0].radius = { 1,1 };
					rect[0].AA_type = { 0xffffffff,0 };
					break;
				}

			}
		}
		else {
			采样器类型 = DEF_ObType_SamplerType_2DArray;
			//rect[0].offset = {};
			//rect[0].size = self->m_Size;
			//rect[0].size.y -= 24;
			rect[0].radius = { 1,1 };
			rect[0].AA_type = { 0xffffffff,0 };
		}
		
		switch (f_prop_enum(box.m_纹理绘制模式)) {
			case 0:
				break;
			case 1:
				break;
			case 2:
				纹理绘制类型 = DEF_DrawType_Depth;
				break;
			default:
				break;
		}
		//rect.color_type.y = f_prop_enum(box.m_纹理绘制模式);
		纹理ID[0] = p.m_激活ID;
	}
	else {
		采样器类型 = DEF_ObType_SamplerType_2DArray;
		纹理数量 = 1;
		纹理ID[0] = 0;
	}

	f_vg_setTextureRect(self->m_画布, box.m_纹理绘制, 元素数量, 形状, rect, 纹理ID);
	f_vg_setTextures(self->m_画布, box.m_纹理绘制, 纹理数量, &ts, 纹理绘制类型, 采样器类型);
}

C_图像集视口::C_图像集视口(S_UI渲染环境& ctx) :C_Widget(&ctx) {
	mf_布局 = f_图像集视口布局;
	mf_绘制 = f_图像集视口绘制;
	mf_变换 = f_图像集视口变换;

	m_默认纹理集 = f_纹理集_创建();
	f_纹理集_add纹理(m_默认纹理集, S_全局缓存::g_空纹理);

	m_纹理 = {};
	m_纹理属性 = {};

	m_纹理绘制模式 = f_alloc_EnumProp(nullptr, { {u"RGB"},{u"线性"}, {u"深度"}, {u"环境"} }, u"绘制模式");
	m_纹理绘制模式.m_私有 = true;

	auto* 绘制模式 = f_ui_创建枚举选择框(ctx, E_方向::e_横向);
	绘制模式->f_bind属性(m_纹理绘制模式);
	f_添加子组件(绘制模式);

}

C_图像集视口::~C_图像集视口() {
	if (m_默认纹理集) f_纹理集_销毁(m_默认纹理集);

	f_prop_Release(m_纹理绘制模式);
}

C_Widget* f_ui_创建图像集视口(S_UI渲染环境& ctx) {
	C_图像集视口* box = new C_图像集视口(ctx);
	return box;
}

void f_ui_bind图像集视口属性(C_Widget* self, S_Props& prop) {
	C_图像集视口& box = *dynamic_cast<C_图像集视口*>(self);
	box.m_纹理 = prop;

	auto p = f_prop_纹理集(box.m_纹理);
	
	switch (p.m_DrawMode) {
		case DEF_DrawType_Depth: {
			f_prop_enum(box.m_纹理绘制模式) = 2;
			break;
		}
		default:
			f_prop_enum(box.m_纹理绘制模式) = 0;
			break;
	}
	box.m_纹理绘制模式.m_UI->m_Update = on_纹理绘制模式切换;

	self->m_更新绘制属性 = true;
}





static void f_图形视口_布局(C_Widget* self, C_Widget** w, uint32 num) {
	
}

static void f_图形视口_绘制(C_Widget* self, S_2D画布* 画布) {
	C_图形视口& box = *dynamic_cast<C_图形视口*>(self);

	box.m_元素ID = f_vg_genVGraph(画布, u"节点");

}

static void f_图形视口_变换(C_Widget* self) {
	C_图形视口& box = *dynamic_cast<C_图形视口*>(self);

	f_vg_drawVGraph(self->m_画布, u"节点", box.m_元素ID);
}

C_图形视口::C_图形视口(S_UI渲染环境& ctx) : C_Widget(&ctx) {
	mf_布局 = f_图形视口_布局;
	mf_绘制 = f_图形视口_绘制;
	mf_变换 = f_图形视口_变换;

	f_widget_添加绘制画布(this);
}

C_图形视口::~C_图形视口() {
	
}


C_Widget* f_ui_创建矢量图形视口(S_UI渲染环境& ctx) {
	C_图形视口* box = new C_图形视口(ctx);
	return box;
}

void f_ui_set矢量视图图形对象(C_Widget* self, const std::u16string& name) {
	C_图形视口& box = *dynamic_cast<C_图形视口*>(self);

	box.m_图形对象名称 = name;
	box.m_画布->m_是否重绘 = true;
}







